import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
  Card,
  Table,
  Button,
  Input,
  Space,
  Modal,
  Form,
  Select,
  TreeSelect,
  Tag,
  Popconfirm,
  Toast,
  Typography,
  Row,
  Col,
  Tree,
  InputNumber,
} from '@douyinfe/semi-ui';
import {
  IconPlus,
  IconSearch,
  IconEdit,
  IconDelete,
  IconRefresh,
  IconTreeTriangleDown,
  IconTreeTriangleRight,
  IconCode,
} from '@douyinfe/semi-icons';
import { menuApi, SysMenu } from '../../api/menu';
import MenuSyncTool from '../../components/MenuSyncTool';

const { Title } = Typography;
const { Column } = Table;

interface MenuTreeNode {
  key: string;
  label: string;
  value: number;
  children?: MenuTreeNode[];
}

const MenuManagement: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [menus, setMenus] = useState<SysMenu[]>([]);
  const [menuTree, setMenuTree] = useState<MenuTreeNode[]>([]);
  const [keyword, setKeyword] = useState('');
  const [modalVisible, setModalVisible] = useState(false);
  const [editingMenu, setEditingMenu] = useState<SysMenu | null>(null);
  const [syncToolVisible, setSyncToolVisible] = useState(false);
  const [selectedMenuForSync, setSelectedMenuForSync] = useState<number | undefined>(undefined);
  const formRef = useRef<any>();
  const [expandedKeys, setExpandedKeys] = useState<string[]>([]);

  useEffect(() => {
    loadMenus();
  }, []);

  const loadMenus = async () => {
    try {
      setLoading(true);
      const data = await menuApi.getMenuTree();
      setMenus(data);
    } catch (error) {
      console.error('加载菜单失败:', error);
      Message.error('加载菜单失败');
    } finally {
      setLoading(false);
    }
  };

  const buildMenuTree = (menuList: SysMenu[]) => {
    const tree: MenuTreeNode[] = [];
    const menuMap = new Map<number, SysMenu>();
    
    // 创建菜单映射
    menuList.forEach(menu => {
      menuMap.set(menu.id!, menu);
    });
    
    // 构建树形结构
    const buildNode = (menu: SysMenu): MenuTreeNode => {
      const children = menuList
        .filter(item => item.parentId === menu.id)
        .map(child => buildNode(child));
      
      return {
        key: menu.id!.toString(),
        label: menu.menuName,
        value: menu.id!,
        children: children.length > 0 ? children : undefined,
      };
    };
    
    // 获取根节点
    const rootMenus = menuList.filter(menu => menu.parentId === 0 || menu.parentId === null);
    rootMenus.forEach(menu => {
      tree.push(buildNode(menu));
    });
    
    setMenuTree(tree);
  };

  const handleSearch = () => {
    if (!keyword.trim()) {
      loadMenus();
      return;
    }
    
    const filteredMenus = menus.filter(menu => 
      menu.menuName.toLowerCase().includes(keyword.toLowerCase()) ||
      (menu.menuPath && menu.menuPath.toLowerCase().includes(keyword.toLowerCase()))
    );
    setMenus(filteredMenus);
  };

  const handleReset = () => {
    setKeyword('');
    loadMenus();
  };

  const handleAdd = useCallback(() => {
    setEditingMenu(null);
    if (formRef.current) {
      formRef.current.reset();
      // 设置默认值
      formRef.current.setValues({
        parentId: 0,
        menuType: 1,
        isFrame: 0,
        isCache: 1,
        visible: 1,
        sortOrder: 1,
        status: 1
      });
    }
    setModalVisible(true);
  }, []);

  const handleEdit = useCallback((menu: SysMenu) => {
    setEditingMenu(menu);
    if (formRef.current) {
      formRef.current.setValues({
        parentId: menu.parentId,
        menuName: menu.menuName,
        menuPath: menu.menuPath,
        menuIcon: menu.menuIcon,
        menuType: menu.menuType,
        permission: menu.permission,
        component: menu.component,
        isFrame: menu.isFrame,
        isCache: menu.isCache,
        visible: menu.visible,
        sortOrder: menu.sortOrder,
        status: menu.status
      });
    }
    setModalVisible(true);
  }, []);

  const handleGenerateFiles = (menu: SysMenu) => {
    if (menu.menuType !== 2) {
      Toast.warning('只能为页面类型的菜单生成文件');
      return;
    }
    setSelectedMenuForSync(menu.id);
    setSyncToolVisible(true);
  };

  const handleDelete = async (id: number) => {
    try {
      await menuApi.deleteMenu(id);
      Toast.success('删除成功');
      loadMenus();
    } catch (error) {
      console.error('删除失败:', error);
    }
  };

  const handleSubmit = async (values: any) => {
    try {
      if (editingMenu) {
        await menuApi.updateMenu(editingMenu.id, values);
        Toast.success('更新成功');
      } else {
        await menuApi.createMenu(values);
        Toast.success('创建成功');
      }
      setModalVisible(false);
      loadMenus();
    } catch (error) {
      console.error('操作失败:', error);
    }
  };

  const getStatusTag = (status: number) => {
    return status === 1 ? (
      <Tag color="green">启用</Tag>
    ) : (
      <Tag color="red">禁用</Tag>
    );
  };

  const getMenuTypeTag = (type: number) => {
    switch (type) {
      case 1:
        return <Tag color="blue">目录</Tag>;
      case 2:
        return <Tag color="green">菜单</Tag>;
      case 3:
        return <Tag color="orange">按钮</Tag>;
      default:
        return <Tag color="grey">未知</Tag>;
    }
  };

  const getParentMenuName = (parentId: number) => {
    if (parentId === 0 || parentId === null) return '根目录';
    const parentMenu = menus.find(menu => menu.id === parentId);
    return parentMenu ? parentMenu.menuName : '未知';
  };

  const flattenMenus = (menuList: SysMenu[], level = 0): any[] => {
    const result: any[] = [];
    
    const rootMenus = menuList.filter(menu => menu.parentId === 0 || menu.parentId === null);
    
    const addMenuWithChildren = (menu: SysMenu, currentLevel: number) => {
      result.push({
        ...menu,
        level: currentLevel,
        key: menu.id,
      });
      
      const children = menuList.filter(item => item.parentId === menu.id);
      children.forEach(child => addMenuWithChildren(child, currentLevel + 1));
    };
    
    rootMenus.forEach(menu => addMenuWithChildren(menu, 0));
    
    return result;
  };

  const flatMenus = flattenMenus(menus);

  const columns = [
    {
      title: '菜单名称',
      dataIndex: 'menuName',
      width: 200,
      render: (text: string, record: any) => (
        <div style={{ paddingLeft: record.level * 20 }}>
          {record.level > 0 && (
            <span className="text-gray-400 mr-2">
              {'└'.repeat(record.level)}
            </span>
          )}
          {text}
        </div>
      ),
    },
    {
      title: '图标',
      dataIndex: 'menuIcon',
      width: 80,
      render: (icon: string) => (
        icon ? (
          <i className={`${icon} text-lg`} />
        ) : (
          <span className="text-gray-400">-</span>
        )
      ),
    },
    {
      title: '路径',
      dataIndex: 'menuPath',
      width: 200,
      render: (path: string) => (
        path ? (
          <code className="bg-gray-100 px-2 py-1 rounded text-sm">
            {path}
          </code>
        ) : (
          <span className="text-gray-400">-</span>
        )
      ),
    },
    {
      title: '类型',
      dataIndex: 'menuType',
      width: 80,
      render: (type: number) => {
        // 根据路径判断类型：目录(无路径)、菜单(有路径)、按钮(特殊标识)
        if (!type) {
          return <Tag color="grey">-</Tag>;
        }
        return getMenuTypeTag(type);
      },
    },
    {
      title: '排序',
      dataIndex: 'sortOrder',
      width: 80,
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 80,
      render: (status: number) => getStatusTag(status),
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      width: 160,
      render: (time: string) => time?.substring(0, 19),
    },
    {
      title: '操作',
      width: 230,
      render: (record: SysMenu) => (
        <Space>
          <Button
            theme="borderless"
            type="primary"
            size="small"
            icon={<IconEdit />}
            onClick={() => handleEdit(record)}
          >
            编辑
          </Button>
          {record.menuType === 2 && (
            <Button
              theme="borderless"
              type="secondary"
              size="small"
              icon={<IconCode />}
              onClick={() => handleGenerateFiles(record)}
            >
              生成文件
            </Button>
          )}
          <Popconfirm
            title="确定删除这个菜单吗？"
            content="删除后子菜单也会被删除，请谨慎操作！"
            onConfirm={() => handleDelete(record.id!)}
          >
            <Button
              theme="borderless"
              type="danger"
              size="small"
              icon={<IconDelete />}
            >
              删除
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div className="space-y-4">
      <Card>
        <div className="flex justify-between items-center mb-4">
          <Title heading={4}>菜单管理</Title>
          <Button
            type="primary"
            icon={<IconPlus />}
            onClick={handleAdd}
          >
            新增菜单
          </Button>
        </div>

        <Row gutter={16} className="mb-4">
          <Col span={8}>
            <Input
              placeholder="搜索菜单名称、路径"
              value={keyword}
              onChange={setKeyword}
              onEnterPress={handleSearch}
            />
          </Col>
          <Col>
            <Space>
              <Button
                type="primary"
                icon={<IconSearch />}
                onClick={handleSearch}
              >
                搜索
              </Button>
              <Button
                icon={<IconRefresh />}
                onClick={handleReset}
              >
                重置
              </Button>
            </Space>
          </Col>
        </Row>

        <Table
          columns={columns}
          dataSource={flatMenus}
          loading={loading}
          pagination={false}
          rowKey="id"
        />
      </Card>

      {/* 菜单表单弹窗 */}
      <Modal
        title={editingMenu ? '编辑菜单' : '新增菜单'}
        open={modalVisible}
        onCancel={() => setModalVisible(false)}
        footer={null}
        width={600}
      >
        <Form
          getFormApi={(formApi) => (formRef.current = formApi)}
          onSubmit={handleSubmit}
          labelPosition="left"
          labelWidth={100}
          labelAlign="left"
          autoScrollToError
          showValidateIcon
          onSubmitFail={(errors) => {
            console.error('表单验证失败:', errors);
            Toast.error('请检查表单输入');
          }}
        >
          <Form.TreeSelect
            field="parentId"
            label="上级菜单"
            placeholder="请选择上级菜单"
            treeData={[
              { key: '0', label: '根目录', value: 0 },
              ...menuTree,
            ]}
            searchable
            filterTreeNode
          />
          
          <Form.Input
            field="menuName"
            label="菜单名称"
            placeholder="请输入菜单名称"
            rules={[{ required: true, message: '请输入菜单名称' }]}
          />
          
          <Form.Input
            field="menuPath"
            label="菜单路径"
            placeholder="请输入菜单路径，如：/system/user"
            rules={[
              { pattern: /^\/.*/, message: '路径必须以 / 开头' },
            ]}
          />
          
          <Form.Input
            field="menuIcon"
            label="菜单图标"
            placeholder="请输入图标类名，如：IconUser"
          />
          
          <Form.Select
            field="menuType"
            label="菜单类型"
            placeholder="请选择菜单类型"
            rules={[{ required: true, message: '请选择菜单类型' }]}
          >
            <Select.Option value={1}>目录</Select.Option>
            <Select.Option value={2}>菜单</Select.Option>
            <Select.Option value={3}>按钮</Select.Option>
          </Form.Select>
          
          <Form.Input
            field="permission"
            label="权限标识"
            placeholder="请输入权限标识，如：system:user:list"
          />
          
          <Form.Input
            field="component"
            label="组件路径"
            placeholder="请输入组件路径，如：system/user/index"
          />
          
          <Form.Select
            field="isFrame"
            label="是否外链"
            placeholder="请选择是否外链"
          >
            <Select.Option value={0}>否</Select.Option>
            <Select.Option value={1}>是</Select.Option>
          </Form.Select>
          
          <Form.Select
            field="isCache"
            label="是否缓存"
            placeholder="请选择是否缓存"
          >
            <Select.Option value={0}>不缓存</Select.Option>
            <Select.Option value={1}>缓存</Select.Option>
          </Form.Select>
          
          <Form.Select
            field="visible"
            label="是否可见"
            placeholder="请选择是否可见"
          >
            <Select.Option value={0}>隐藏</Select.Option>
            <Select.Option value={1}>显示</Select.Option>
          </Form.Select>
          
          <Form.InputNumber
            field="sortOrder"
            label="排序号"
            placeholder="请输入排序号"
            min={1}
            max={999}
            rules={[{ required: true, message: '请输入排序号' }]}
          />
          
          <Form.Select
            field="status"
            label="状态"
            placeholder="请选择状态"
            rules={[{ required: true, message: '请选择状态' }]}
          >
            <Select.Option value={1}>启用</Select.Option>
            <Select.Option value={0}>禁用</Select.Option>
          </Form.Select>
          
          <div className="flex justify-end space-x-2 mt-6">
            <Button onClick={() => setModalVisible(false)}>
              取消
            </Button>
            <Button type="primary" htmlType="submit">
              确定
            </Button>
          </div>
        </Form>
      </Modal>

      {/* 菜单同步工具弹窗 */}
      <MenuSyncTool
        visible={syncToolVisible}
        onCancel={() => {
          setSyncToolVisible(false);
          setSelectedMenuForSync(undefined);
        }}
        selectedMenuId={selectedMenuForSync}
      />
    </div>
  );
};

export default MenuManagement;